package com.xnyzc.lhy.mis.service.impl.user;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xnyzc.lhy.common.constant.MessageConstant;
import com.xnyzc.lhy.common.exception.PangException;
import com.xnyzc.lhy.common.penum.EErrorCode;
import com.xnyzc.lhy.common.penum.client.EClientUserType;
import com.xnyzc.lhy.common.penum.pay.EPayMoneyLock;
import com.xnyzc.lhy.common.penum.user.EOaCUserEmailStatus;
import com.xnyzc.lhy.common.penum.user.EOaCUserIdentityVerfied;
import com.xnyzc.lhy.common.penum.user.EOaCUserIsBlocked;
import com.xnyzc.lhy.common.penum.user.EOaCUserSex;
import com.xnyzc.lhy.common.penum.user.EOaCUserType;
import com.xnyzc.lhy.common.penum.user.info.EOaCUserInfoAgreement;
import com.xnyzc.lhy.common.penum.user.info.EOacUserInfoAuditType;
import com.xnyzc.lhy.common.penum.user.info.EOacUserInfoIdentityType;
import com.xnyzc.lhy.common.penum.wallet.EIsDepartmentMoneyDisplayType;
import com.xnyzc.lhy.common.util.CheckUtil;
import com.xnyzc.lhy.common.util.IDUtil;
import com.xnyzc.lhy.mis.entity.result.cms.user.CmsOaCUserImport;
import com.xnyzc.lhy.mis.entity.sidebar.OaCUserOffice;
import com.xnyzc.lhy.mis.entity.sidebar.OaSysOffice;
import com.xnyzc.lhy.mis.entity.sidebar.OaSysSidebar;
import com.xnyzc.lhy.mis.entity.system.OaSysGlobalConfig;
import com.xnyzc.lhy.mis.entity.user.OaCUser;
import com.xnyzc.lhy.mis.entity.user.OaCUserInfo;
import com.xnyzc.lhy.mis.entity.user.tab.OaTabUser;
import com.xnyzc.lhy.mis.entity.user.wallet.OaCWallet;
import com.xnyzc.lhy.mis.mapper.sidebar.OaSysOfficeMapper;
import com.xnyzc.lhy.mis.mapper.system.OaSysGlobalConfigMapper;
import com.xnyzc.lhy.mis.service.cms.user.ICmsOaCUserImportService;
import com.xnyzc.lhy.mis.service.oss.IOaFileService;
import com.xnyzc.lhy.mis.service.sidebar.IOaCUserOfficeService;
import com.xnyzc.lhy.mis.service.sidebar.IOaSysSidebarService;
import com.xnyzc.lhy.mis.service.user.IOaCUserInfoService;
import com.xnyzc.lhy.mis.service.user.IOaCUserService;
import com.xnyzc.lhy.mis.service.user.tab.IOaTabUserService;
import com.xnyzc.lhy.mis.service.user.wallet.IOaCWalletService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description 用户导入
 * @Author zhuyubin
 * @Date 2019-08-28 16:47
 **/
@Service
public class CmsOaCUserImportServiceImpl implements ICmsOaCUserImportService {

    @Autowired
    private IOaCUserService iOaCUserService;
    @Autowired
    private IOaCUserInfoService iOaCUserInfoService;
    @Autowired
    private IOaCUserOfficeService iOaCUserOfficeService;
    @Autowired
    private IOaCWalletService iOaCWalletService;
    @Autowired
    private IOaFileService iOaFileService;
    @Autowired
    private OaSysGlobalConfigMapper oaSysGlobalConfigMapper;
    @Autowired
    private OaSysOfficeMapper oaSysOfficeMapper;
    @Autowired
    private IOaTabUserService iOaTabUserService;
    @Autowired
    private IOaSysSidebarService iOaSysSidebarService;

    /**
     * 获取模板url
     * @param tag
     * @return
     */
    @Override
    public String getUserImportFile(String tag, Integer type){
        OaSysGlobalConfig oaSysGlobalConfig = oaSysGlobalConfigMapper.selectOne(Wrappers.<OaSysGlobalConfig>lambdaQuery().eq(OaSysGlobalConfig::getTag, tag));
        if (CheckUtil.objIsEmpty(oaSysGlobalConfig)){
            return null;
        }
        if (EClientUserType.c.getValue().equals(type)){
            return iOaFileService.getFileUrl(oaSysGlobalConfig.getUserImportFileId());
        } else {
            return iOaFileService.getFileUrl(oaSysGlobalConfig.getDriverImportFileId());
        }

    }

    /**
     * 导入
     * @param sysUserId 后台用户
     * @param tag 租户
     * @param cmsOaCUserImportList 表格数据
     * @return
     */
    @Override
    public String userImport(Long sysUserId, String tag, List<CmsOaCUserImport> cmsOaCUserImportList){
        Date date = new Date();
        // 查重查空
        Map<String, Integer> phoneMap = new HashMap<>();
        // 批量插入用户
        List<OaCUser> oaCUserList = new ArrayList<>();
        // 批量插入用户部门关联
        List<OaCUserOffice> oaCUserOfficeList = new ArrayList<>();
        // 批量插入用户信息
        List<OaCUserInfo> oaCUserInfoList = new ArrayList<>();
        // 批量插入用户钱包
        List<OaCWallet> oaCWalletList = new ArrayList<>();
        // 批量插入Tab权限
        List<OaTabUser> oaTabUserList = new ArrayList<>();
        // 批量插入侧边栏权限
        List<OaSysSidebar> oaSysSidebarList = new ArrayList<>();
        // 查重
        List<OaCUser> oaCUsers = iOaCUserService.list(Wrappers.<OaCUser>lambdaQuery().eq(OaCUser::getTag, tag));
        // 对比数据库重复手机号
        StringBuffer repeatPhone = new StringBuffer();
        boolean isRepeatPhone = false;
        repeatPhone.append("<p>").append(MessageConstant.REPEAT_PHONE).append(":</p>");
        // 前部机构
        List<OaSysOffice> offices = oaSysOfficeMapper.selectList(Wrappers.<OaSysOffice>lambdaQuery().eq(OaSysOffice::getTag, tag));
        for (CmsOaCUserImport cmsOaCUserImport : cmsOaCUserImportList) {
            String userPhone = cmsOaCUserImport.getUserPhone();
            Long officeId = cmsOaCUserImport.getOfficeCode();
            if (CheckUtil.objIsEmpty(userPhone, officeId)){
                throw PangException.create(EErrorCode.impNull);
            }
            if (phoneMap.containsKey(userPhone)){
                throw PangException.create(EErrorCode.impRepeatPhone);
            }
            phoneMap.put(userPhone, 1);
            for (OaCUser oaCUser : oaCUsers) {
                String userUserPhone = oaCUser.getUserPhone();
                if (userPhone.equals(userUserPhone)){
                    isRepeatPhone = true;
                    repeatPhone.append("<p>").append(userPhone).append("</p>");
                    break;
                }
            }
            // 用户放入待插入列表
            OaCUser oaCUser = this.insertOaCUserBean(sysUserId, tag, userPhone, date, cmsOaCUserImport);
            Long userId = oaCUser.getUserId();
            oaCUserList.add(oaCUser);
            // 用户机构关联入待插入列表
            oaCUserOfficeList.add(this.insertOaCUserOffice(userId, sysUserId, tag, date, officeId, offices));
            // 用户信息
            oaCUserInfoList.add(this.insertOaCUserInfo(userId, sysUserId, tag, date, cmsOaCUserImport));
            // 用户钱包
            oaCWalletList.add(this.insertOaCWallet(userId, sysUserId, officeId, tag, date));
            // tab权限
            oaTabUserList.add(this.insertOaTabUserBean(userId, tag, sysUserId, date));
            // 侧边栏权限
            oaSysSidebarList.add(this.insertOaSysSidebarBean(userId, tag, sysUserId, date));
        }
        repeatPhone = repeatPhone.deleteCharAt(repeatPhone.length() - 1);
        if (isRepeatPhone){
            throw PangException.create(EErrorCode.impDBRepeatPhone, repeatPhone.toString());
        }
        boolean b = iOaCUserService.saveBatch(oaCUserList);
        if (!b){
            throw PangException.create(EErrorCode.impFailure);
        }
        b = iOaCUserInfoService.saveBatch(oaCUserInfoList);
        if (!b){
            throw PangException.create(EErrorCode.impFailure);
        }
        b = this.iOaCUserOfficeService.saveBatch(oaCUserOfficeList);
        if (!b){
            throw PangException.create(EErrorCode.impFailure);
        }
        b = iOaCWalletService.saveBatch(oaCWalletList);
        if (!b){
            throw PangException.create(EErrorCode.impFailure);
        }
        b = iOaTabUserService.saveBatch(oaTabUserList);
        if (!b){
            throw PangException.create(EErrorCode.impFailure);
        }
        b = iOaSysSidebarService.saveBatch(oaSysSidebarList);
        if (!b){
            throw PangException.create(EErrorCode.impFailure);
        }
        return EErrorCode.impSuccess.getDesc();
    }

    /**
     * 用户钱包信息 待插入实体
     * @param userId 用户id
     * @param sysUserId 后台用户id
     * @param officeId 机构id
     * @param tag 租户
     * @param date 当前时间
     * @return
     */
    private OaCWallet insertOaCWallet(Long userId, Long sysUserId, Long officeId, String tag, Date date){
        BigDecimal zero = new BigDecimal("0");
        OaCWallet oaCWallet = new OaCWallet();
        oaCWallet.setWalletId(IDUtil.nextId());
        oaCWallet.setUserId(userId);
        oaCWallet.setOfficeId(officeId);
        oaCWallet.setWalletBalance(zero);
        oaCWallet.setIsBalancelPay(EPayMoneyLock.yes.getType());
        oaCWallet.setPersonalOfficialBalance(zero);
        oaCWallet.setIsPersonalAmount(EIsDepartmentMoneyDisplayType.yes.getType());
        oaCWallet.setIsPersonalPay(EPayMoneyLock.yes.getType());
        oaCWallet.setDeptOfficialBalance(zero);
        oaCWallet.setIsDeptAmount(EIsDepartmentMoneyDisplayType.yes.getType());
        oaCWallet.setIsDeptPay(EPayMoneyLock.yes.getType());
        oaCWallet.setTag(tag);
        oaCWallet.setCreateUser(sysUserId);
        oaCWallet.setCreateTime(date);
        oaCWallet.setUpdateUser(sysUserId);
        oaCWallet.setUpdateTime(date);
        return oaCWallet;
    }

    /**
     * 用户信息 待插入实体
     * @param userId 用户id
     * @param sysUserId 后台用户id
     * @param tag 租户
     * @param date 当前时间
     * @param cmsOaCUserImport ex表格数据
     * @return
     */
    private OaCUserInfo insertOaCUserInfo(Long userId, Long sysUserId, String tag, Date date, CmsOaCUserImport cmsOaCUserImport){
        OaCUserInfo oaCUserInfo = new OaCUserInfo();
        oaCUserInfo.setInfoId(IDUtil.nextId());
        oaCUserInfo.setUserId(userId);
        oaCUserInfo.setAddress(cmsOaCUserImport.getAddress());
        oaCUserInfo.setIdentityNumber(cmsOaCUserImport.getIdentityNumber());
        oaCUserInfo.setIdentityType(EOacUserInfoIdentityType.IDCard.getValue());
        oaCUserInfo.setPassingDate(date);
        oaCUserInfo.setEmergencyContact(cmsOaCUserImport.getEmergencyContact());
        oaCUserInfo.setEmergencyMobile(cmsOaCUserImport.getEmergencyMobile());
        oaCUserInfo.setEmergencyAddress(cmsOaCUserImport.getEmergencyAddress());
        oaCUserInfo.setAuditType(EOacUserInfoAuditType.manualReview.getValue());
        oaCUserInfo.setAgreement(EOaCUserInfoAgreement.yes.getValue());
        oaCUserInfo.setTag(tag);
        oaCUserInfo.setCreateUser(sysUserId);
        oaCUserInfo.setCreateTime(date);
        oaCUserInfo.setUpdateUser(sysUserId);
        oaCUserInfo.setUpdateTime(date);
        return oaCUserInfo;
    }

    /**
     * 用户机构关联 待插入实体
     * @param userId
     * @param sysUserId 后台用户id
     * @param tag 租户
     * @param date 当前时间
     * @param officeCode 机构编码
     * @return
     */
    private OaCUserOffice insertOaCUserOffice(Long userId, Long sysUserId, String tag, Date date, Long officeCode, List<OaSysOffice> offices){
        OaCUserOffice oaCUserOffice = new OaCUserOffice();
        for (OaSysOffice office : offices) {
            if (officeCode.equals(Long.valueOf(office.getCode()))){
                oaCUserOffice.setOfficeId(office.getOfficeId());
            }
        }
        if (CheckUtil.objIsEmpty(oaCUserOffice.getOfficeId())){
            StringBuffer stringBuffer = new StringBuffer();
            stringBuffer.append("<p>").append(EErrorCode.unOfficeCode.getDesc()).append(":</p>");
            stringBuffer.append("<p>").append(officeCode).append("</p>");
            throw PangException.create(EErrorCode.unOfficeCode, stringBuffer.toString());
        }
        oaCUserOffice.setLinkedId(IDUtil.nextId());
        oaCUserOffice.setUserId(userId);
        oaCUserOffice.setTag(tag);
        oaCUserOffice.setCreateUser(sysUserId);
        oaCUserOffice.setCreateTime(date);
        oaCUserOffice.setUpdateUser(sysUserId);
        oaCUserOffice.setUpdateTime(date);
        return oaCUserOffice;
    }

    /**
     * 用户待插入实体
     * @param sysUserId 后台用户id
     * @param tag 租户
     * @param userPhone 用户手机号
     * @param date 当前时间
     * @param cmsOaCUserImport ex表格数据
     * @return
     */
    private OaCUser insertOaCUserBean(Long sysUserId, String tag, String userPhone, Date date, CmsOaCUserImport cmsOaCUserImport){
        OaCUser oaCUser = new OaCUser();
        oaCUser.setUserId(IDUtil.nextId());
        oaCUser.setUserPhone(userPhone);
        oaCUser.setUserName(cmsOaCUserImport.getUserName());
        oaCUser.setSex(EOaCUserSex.findByDesc(cmsOaCUserImport.getSex()).getValue());
        String email = cmsOaCUserImport.getEmail();
        if (CheckUtil.objIsNotEmpty(email)){
            oaCUser.setEmail(email);
            oaCUser.setEmailStatus(EOaCUserEmailStatus.yes.getValue());
        } else {
            oaCUser.setEmailStatus(EOaCUserEmailStatus.no.getValue());
        }
        oaCUser.setIsBlocked(EOaCUserIsBlocked.normal.getValue());
        oaCUser.setIdentityVerfied(EOaCUserIdentityVerfied.examinationPassed.getValue());
        oaCUser.setTag(tag);
        oaCUser.setUserType(EOaCUserType.enterprise.getValue());
        oaCUser.setCreateUser(sysUserId);
        oaCUser.setCreateTime(date);
        oaCUser.setUpdateUser(sysUserId);
        oaCUser.setUpdateTime(date);
        return oaCUser;
    }

    /**
     * Tab权限关联
     * @param userId 乘客id
     * @param tag 用户来源
     * @param sysUserId 当前登录人id
     * @param date 当前时间
     * @return
     */
    private OaTabUser insertOaTabUserBean(Long userId, String tag, Long sysUserId, Date date){
        OaTabUser oaTabUser = new OaTabUser();
        oaTabUser.setLinkedId(IDUtil.nextId());
        oaTabUser.setUserId(userId);
        oaTabUser.setTabId(0);
        oaTabUser.setUserType(0);
        oaTabUser.setTag(tag);
        oaTabUser.setCreateUser(sysUserId);
        oaTabUser.setCreateTime(date);
        oaTabUser.setUpdateUser(sysUserId);
        oaTabUser.setUpdateTime(date);
        return oaTabUser;
    }

    /**
     * 侧边栏关联表
     * @param userId 乘客id
     * @param tag 用户来源
     * @param sysUserId 当前登录人id
     * @param date 当前时间
     * @return
     */
    private OaSysSidebar insertOaSysSidebarBean(Long userId, String tag, Long sysUserId, Date date){
        OaSysSidebar oaSysSidebar = new OaSysSidebar();
        oaSysSidebar.setSidebarId(IDUtil.nextId());
        oaSysSidebar.setUserId(userId);
        oaSysSidebar.setDictIds("38,39,67");
        oaSysSidebar.setDictAssociatedIds("23,");
        oaSysSidebar.setHaveSpecifiedVehicle(0);
        oaSysSidebar.setType("1");
        oaSysSidebar.setTag(tag);
        oaSysSidebar.setCreateUser(sysUserId);
        oaSysSidebar.setCreateTime(date);
        oaSysSidebar.setUpdateUser(sysUserId);
        oaSysSidebar.setUpdateTime(date);
        return oaSysSidebar;
    }
}
